package com.company.exp2.context.impl;

import com.company.exp2.context.Context;
import com.company.exp2.factory.EventFactory;
import com.company.exp2.factory.StationFactory;
import com.company.exp2.station.Station;
import com.company.exp2.typeEnum.EventType;

import java.util.HashMap;
import java.util.Map;

/**
 * @author dyy
 */
public class DefaultContext extends Context {

    Map<Integer, Station> stationMap;

    {
        stationMap = new HashMap<>();
    }

    @Override
    public void onChannelTransmittable(long timestamp) {
        onTransmissionComplete();
        stationMap.values().forEach(station -> station.onChannelTransmittable(timestamp));
    }

    @Override
    protected void logAllStationResult() {
        stationMap.values().forEach(Station::log);
    }

    @Override
    public void onChannelForbidden(long timestamp) {
        stationMap.values().forEach(station -> station.onChannelForbidden(timestamp));
    }

    @Override
    public boolean isVacant() {
        return currentTransmittingFrame == null;
    }

    @Override
    protected void registerStation(Station station) {
        int no = generateNextStationNo();
        station.setNo(no);
        stationMap.put(no, station);
    }

    @Override
    public int getStationSize() {
        return stationMap.size();
    }

    @Override
    protected void init() {
        // 自己测五个站点
        for (int i = 0 ; i < 5 ; i++) {
            registerStation(StationFactory.createDefaultInstance());
        }
        // 逐个声明创建Frame事件
        stationMap.values().forEach(station -> getTimeLine().announceAnEvent(
                EventFactory.createInstance(
                        EventType.CREATE_FRAME,
                        0,
                        station
                )
        ));
        // 声明最初的 CHANNEL_TRANSMITTABLE 事件
        getTimeLine().announceAnEvent(
                EventFactory.createInstance(
                        EventType.CHANNEL_TRANSMITTABLE,
                        0,
                        null
                )
        );
    }

    private int generateNextStationNo() {
        return stationMap.size() + 1;
    }

}
